package com.ruoyi.project.mahjong.service.impl;


import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.RecordEntityUtil;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.redis.RedisCache;
import com.ruoyi.framework.web.domain.server.Sys;
import com.ruoyi.project.mahjong.domain.*;
import com.ruoyi.project.mahjong.domain.enu.*;
import com.ruoyi.project.mahjong.domain.uyil.MemberLogUtil;
import com.ruoyi.project.mahjong.mapper.TMemberMapper;
import com.ruoyi.project.mahjong.mapper.TOpenMoneyMapper;
import com.ruoyi.project.mahjong.mapper.TRecordMapper;
import com.ruoyi.project.mahjong.service.ITMemberLogService;
import com.ruoyi.project.mahjong.service.ITOpenTableService;
import com.ruoyi.project.system.domain.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service
public class MoneyCalculateServiceImpl {


    @Autowired
    private TOpenMoneyMapper tOpenMoneyMapper;
    @Autowired
    private TMemberMapper tMemberMapper;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private ITMemberLogService tMemberLogService;

    @Autowired
    private ITOpenTableService openTableService;
    @Autowired
    private TRecordMapper tRecordMapper;

    /**
     * 单人结束
     * @param tOpenTable
     */
   @Transactional(rollbackFor = RuntimeException.class)
    public void calculate(TOpenTable tOpenTable) {
        //开桌费用
        BigDecimal deskmoney = tOpenTable.getMoney();
        //商品费用
        BigDecimal commodityPrice = calCommidtyPrice(tOpenTable);
        //计算出扣除的总额
        BigDecimal meetMoney = deskmoney.add(commodityPrice);
        TMember member = tMemberMapper.selectTMemberById(Long.valueOf(tOpenTable.getMemberId()));
        //剩余总额
        BigDecimal money = member.getMoney();
        if(money.compareTo(meetMoney)==-1){
            throw new RuntimeException("账户余额不足，请进行充值");
        }
/*        member.setMoney(money.subtract(meetMoney));
        tMemberMapper.updateTMember(member);*/
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Long shopId = redisCache.getCacheObject(Constants.SHOP_SUF + user.getUserId());
        saveLog(shopId, user,member,meetMoney,deskmoney,commodityPrice,tOpenTable);
        //储值余额
       BigDecimal storedMoney = member.getStoredMoney();
        //查看储值余额是否够用，够用进行下一步
        int storedFlag=storedMoney.compareTo(meetMoney);
        //够用 结束
       if(storedFlag!=-1){
           //更新信息
            updateMember(member,meetMoney);
        }else{
           //不够用更新余额
           updateSendMember(member,meetMoney);
       }
      tOpenTable.setStatus(DeskStatusEnum.OK_REFUND.getValue());
      int result = openTableService.updateTOpenTable(tOpenTable);
      if(result==0){
          throw  new RuntimeException("扣款失败！请重试");
      }


    }

    /**
     * 储值余额不充足情况下更新金额
     * @param member
     * @param meetMoney
     */
    private void updateSendMember(TMember member, BigDecimal meetMoney) {
        BigDecimal residueMoney=member.getMoney().subtract(meetMoney);//总额更新
        BigDecimal residueSendoeny=member.getStoredMoney().subtract(meetMoney).add(member.getSendMoney());//赠送金额
        TMember updateMember=new TMember();
        updateMember.setId(member.getId());
        updateMember.setMoney(residueMoney);
        updateMember.setStoredMoney(new BigDecimal(0));
        updateMember.setSendMoney(residueSendoeny);
        updateMember.setTableIng(0L);
        tMemberMapper.updateTMember(updateMember);
    }

    /**
     * 储值余额充足情况下更新金额
     * @param member
     * @param meetMoney
     */
    private void updateMember(TMember member, BigDecimal meetMoney) {
        BigDecimal residueMoney=member.getMoney().subtract(meetMoney);//总额更新
        BigDecimal residueStroedMoeny=member.getStoredMoney().subtract(meetMoney);//储值金额
        TMember updateMember=new TMember();
        updateMember.setId(member.getId());
        updateMember.setMoney(residueMoney);
        updateMember.setStoredMoney(residueStroedMoeny);
        updateMember.setTableIng(0L);
        tMemberMapper.updateTMember(updateMember);
    }

    /**
     * 存储日志
     * @param shopId 店铺id
     * @param user 当前操作人员
     * @param member 会员信息
     * @param meetMoney 结算费用
     * @param deskmoney 开桌费用
     * @param commodityPrice 商品费用
     * @param tOpenTable 开桌信息
     */
    public void saveLog(Long shopId, SysUser user, TMember member, BigDecimal meetMoney, BigDecimal deskmoney, BigDecimal commodityPrice, TOpenTable tOpenTable) {
        Long jbid = redisCache.getCacheObject(shopId + user.getUserId().toString());
        TRecord t = RecordEntityUtil.recordEntity(
                tOpenTable.getBak2(),
                jbid.toString(),
                user.getUserId(),
                member.getId(),
                shopId,
                member.getName(),
                "3",
                CostType.DESK.getValue(),
                tOpenTable.getTableId().toString(),
                ShopIncomeType.INCOME.getValue(),
                "桌子消息费用",
               null,
                null,
                meetMoney.doubleValue(),
                null,
                null,
                CheckoutType.OK.getValue(),
                CheckoutType.NO_REFUND.getValue(),
                null,
                new Date(),
                null,
                null,
                null,
                null,
                null,
                new Date(),
                null
        );
        int i = tRecordMapper.insertTRecord(t);

        TMember tMember = tMemberMapper.selectTMemberById(member.getId());
        BigDecimal decimal = tMember.getMoney().subtract(deskmoney).subtract(commodityPrice);
        TMemberLog tMemberLog = MemberLogUtil.insertMemberLog(
                shopId,
                user.getUserId(),
                member.getId(),
                null,
                null,
                null,
                meetMoney.toString(),
                MemberLogType.XF.getValue() ,
                "开桌费:" + deskmoney + ",商品消费:" + commodityPrice + ",余额:" + decimal,
                tOpenTable.getRemark(),
                decimal
        );
        tMemberLogService.insertTMemberLog(tMemberLog);
    }

    /**
     * 计算该桌子上的消费商品价格
     *
     * @param openTable
     * @return
     */
    public BigDecimal calCommidtyPrice(TOpenTable openTable) {
        List<TOpenMoney> tOpenMonies = tOpenMoneyMapper.selectTOpenMoneyBymemberId(openTable.getMemberId(), openTable.getBak2());
        Double money = tOpenMonies.stream().mapToDouble(obj -> obj.getMoney().doubleValue()).sum();
        return new BigDecimal(money);
    }


}
